%%%-------------------------------------------------------------------
%%% File    : valg_bulk_SUITE.erl
%%% Author  :  <vjache>
%%% Description : 
%%%
%%% Created : 21 Apr 2009 by  <vvorobyov@WS24292>
%%%-------------------------------------------------------------------
-module(valg_bulk_SUITE).

%% Note: This directive should only be used in test suites.
-compile(export_all).

-include("../include/valg.hrl").
-include("../include/test.hrl").
-include_library("ct.hrl").

%%--------------------------------------------------------------------
%% COMMON TEST CALLBACK FUNCTIONS
%%--------------------------------------------------------------------

%%--------------------------------------------------------------------
%% Function: suite() -> Info
%%
%% Info = [tuple()]
%%   List of key/value pairs.
%%
%% Description: Returns list of tuples to set default properties
%%              for the suite.
%%
%% Note: The suite/0 function is only meant to be used to return
%% default data values, not perform any other operations.
%%--------------------------------------------------------------------
suite() ->
    [{timetrap,{minutes,100}}].

%%--------------------------------------------------------------------
%% Function: init_per_suite(Config0) ->
%%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
%%
%% Config0 = Config1 = [tuple()]
%%   A list of key/value pairs, holding the test case configuration.
%% Reason = term()
%%   The reason for skipping the suite.
%%
%% Description: Initialization before the suite.
%%
%% Note: This function is free to add any key/value pairs to the Config
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_suite(Config) ->
	case file:read_file_info(?CONFIG(data_dir,Config)++"triple.txt") of
		{error,enoent} ->
			ct:log("Triples data not exists. Generating..."),
			data_gen_utility:gen_triples(100000,Config),
			ct:log("Triples data generated.");
		{ok,_} ->
			ct:log("Triples data already exist.")
	end,
	util:wait_finish_ex([
					  {util:map_triples2spo(Config),fun()-> ct:log("SPO loaded.") end},
%% 					  {util:map_triples2pso(Config),fun()-> ct:log("PSO loaded.") end},
					  {util:map_triples2osp(Config),fun()-> ct:log("OSP loaded.") end}
					 ]),
    Config.

%%--------------------------------------------------------------------
%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}
%%
%% Config0 = Config1 = [tuple()]
%%   A list of key/value pairs, holding the test case configuration.
%%
%% Description: Cleanup after the suite.
%%--------------------------------------------------------------------
end_per_suite(_Config) ->
    ok.

%%--------------------------------------------------------------------
%% Function: init_per_testcase(TestCase, Config0) ->
%%               Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
%%
%% TestCase = atom()
%%   Name of the test case that is about to run.
%% Config0 = Config1 = [tuple()]
%%   A list of key/value pairs, holding the test case configuration.
%% Reason = term()
%%   The reason for skipping the test case.
%%
%% Description: Initialization before each test case.
%%
%% Note: This function is free to add any key/value pairs to the Config
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_testcase(_TestCase, Config) ->
    Config.

%%--------------------------------------------------------------------
%% Function: end_per_testcase(TestCase, Config0) ->
%%               void() | {save_config,Config1}
%%
%% TestCase = atom()
%%   Name of the test case that is finished.
%% Config0 = Config1 = [tuple()]
%%   A list of key/value pairs, holding the test case configuration.
%%
%% Description: Cleanup after each test case.
%%--------------------------------------------------------------------
end_per_testcase(_TestCase, _Config) ->
    ok.

%%--------------------------------------------------------------------
%% Function: sequences() -> Sequences
%%
%% Sequences = [{SeqName,TestCases}]
%% SeqName = atom()
%%   Name of a sequence.
%% TestCases = [atom()]
%%   List of test cases that are part of the sequence
%%
%% Description: Specifies test case sequences.
%%--------------------------------------------------------------------
sequences() -> 
    [].

%%--------------------------------------------------------------------
%% Function: all() -> TestCases | {skip,Reason}
%%
%% TestCases = [TestCase | {sequence,SeqName}]
%% TestCase = atom()
%%   Name of a test case.
%% SeqName = atom()
%%   Name of a test case sequence.
%% Reason = term()
%%   The reason for skipping all test cases.
%%
%% Description: Returns the list of test cases that are to be executed.
%%--------------------------------------------------------------------
all() -> 
    [j2mv_ol,person_info_kf,friends_pairs].


%%--------------------------------------------------------------------
%% TEST CASES
%%--------------------------------------------------------------------

j2mv_ol() -> 
    [].
j2mv_ol(Config) ->
	V1=vect_mnesia:new_mem_bag(t_spo, [subj,pred,obj]),
	V2=vect_mnesia:new_mem_bag(t_spo, [subj,pred,obj]),
	%V3=vect_mnesia:new_mem_bag(info,[S,P,O,P1,O1]),
	MapExpr1 = {?VECT_TAG,V1},
	MapExpr2 = {?VECT_TAG,V2},
	JoinExpr = {?JOIN_TAG,
				[MapExpr1,MapExpr2],
				fun([{t_spo,S,P,O},{t_spo,S,P1,O1}])-> 
						{info,S,P,O,P1,O1};
				   (X) ->
						exit({bag_out_format,X})
				end },
	Pg=valg:eval(JoinExpr, pipe_logger:new(?CONFIG(priv_dir,Config)++"/join-result")),
%% 	pipe_console:new()),
	ct:log(default,lists:flatten(valg:explain(Pg))),
	util:wait_finish(pgt:new(Pg)),
    ok.

person_info_kf() ->
	[].
person_info_kf(Config) ->
	T_spo=vect_mnesia:new_mem_bag(t_spo, [subj,pred,obj]),
	SPOExpr= {?VECT_TAG,T_spo},
	KFExpr={?KEYFOLD_TAG,SPOExpr, 
			kfm_triple_flattener:new(
			  t_spo,person,
			  [{onto,"name"},
			   {onto,"familyName"},
			   {onto,"age"},
			   {onto,"interest"}])
		   },
	Pg=valg:eval(KFExpr, pipe_logger:new(?CONFIG(priv_dir,Config)++"/keyfold-result")),
	ct:log(default,lists:flatten(valg:explain(Pg))),
	util:wait_finish(pgt:new(Pg)),
	ok.

friends_pairs() ->
	[].
friends_pairs(Config) ->
	T_spo=vect_mnesia:new_mem_bag(t_spo, [subj,pred,obj]),
	SPOExpr= {?VECT_TAG,T_spo},
	KFExpr={?KEYFOLD_TAG,SPOExpr,
			_FoldFun=fun({t_spo,_S,P,_O}=E,Dict)->
					dict:store(P, E, Dict)
			end,
			_Acc0=dict:new(),
			_RecFun=fun(S,Dict) ->
					L=[case dict:find(P, Dict) of
						 {ok,{t_spo,_S,P,{'$lit',Val,_T}}}->
							 Val;
						 {ok,{t_spo,_S,P,{_prefix,_Val}=Val}}->
							 Val;
						 error ->
							 error
					 end||P<-[{onto,"name"},
							  {onto,"familyName"},
							  {onto,"age"},
							  {onto,"interest"},
							  {onto,"friend"}
							 ]],
					list_to_tuple([person,S|L])
			end},
	MapExpr1 = {?MAP_TAG, 
				KFExpr , 
				fun({person,S,Name,FName,Age,Interest,FriendId}=Per)->
						{temp,FriendId,Per}
				end},
	JoinExpr = {?JOIN_TAG,
				[KFExpr,MapExpr1],
				fun([{person,S,Name,FName,Age,Interest,FriendId}=F1,
					 {temp,S,{person,S1,Name1,FName1,Age1,Interest1,S}=F2}])-> 
						{friends,S1,F2,F1};
				   (X) ->
						exit({bag_out_format,X})
				end },
	Pg=valg:eval(JoinExpr, pipe_logger:new(?CONFIG(priv_dir,Config)++"/friends-result")),
	ct:log(default,lists:flatten(valg:explain(Pg))),
	util:wait_finish(pgt:new(Pg)),
    ok.

%% 	T_pso=vect_mnesia:new_mem_bag(t_pso, [pred,subj,obj]),
%% 	T_spo=vect_mnesia:new_mem_bag(t_spo, [subj,pred,obj]),
%% 	Friends = {?VECT_TAG,T_pso,{lookup,{onto,"friend"}}},
%% 	MapExpr = {?MAP_TAG,Friends,
%% 			   fun({t_pso,P,S,O})->
%% 					   {t_spo,S,P,O}
%% 			   end},
%% 	TransExpr = {?TRANSFORM_TAG,MapExpr,
%% 				 fun({t_spo,S,P,O}) ->
%% 						 vect:lookup(S, )},
%% 	T_spo=vect_mnesia:new_mem_bag(t_spo, [subj,pred,obj]),
%% 	V_spo={?VECT_TAG,T_spo},
%% 	JoinExpr = {?JOIN_TAG,
%% 				[MapExpr,V_spo,V_spo],
%% 				fun([{t_spo,S,{onto,"friend"},O},
%% 					 {t_spo,S,,O1},
%% 					 {t_spo,S,P1,O1}])-> 
%% 						{info,S,P,O,P1,O1};
%% 				   (X) ->
%% 						?REJECT_REC
%% 				end },


